/*
 * @Description: 联系人
 * @Author: fhw
 * @Date: 2022-12-31 23:24:34
 */
import { computed, defineComponent, h, reactive, ref, watch } from 'vue'
import { FormFollow, FormSearch, Scroll } from '@/components'
import UserInfo from '@/components/user/userInfo'
import { ContactsFriends, User } from '@/interface'
import { isTrue } from '@/utils/tools'
import { clone, equals } from 'ramda'
import { UserAddOutlined, UsergroupAddOutlined, SearchOutlined, RightOutlined } from '@ant-design/icons-vue'
import './style.scss'
import {
	BuiltInUserMenu,
	BuiltInUserMenuItem,
	onSendMessage,
	PySegSort,
	pySegSort,
	SearchType,
	UserInfoState,
} from './util'
import { MenuItem } from '@/components/user/interface'
import { errorTips, successTips, searchFilter } from '@/utils'
import { IconAddUser } from '@/components/icon'
import NewFriends from './components/newFriends'
import { BasicDataModule } from '@/store/modules/basicData'
import { ContextmenuItem } from '@/components/Contextmenu/interface'
import { ChatUserGroup } from '@/interface/user'
import GroupChatInfo from './components/groupChatInfo'
import UserImg from '@/components/user/userImg'
import { useRouter } from 'vue-router'
const $styles = {
	searchIconSize: '17px',
}
enum DoRightType {
	userInfo = 'UserInfo',
	newFriends = 'NewFriends',
}
interface Callback {
	openUserInfo: (data: ContactsFriends) => void
}
interface UserRenderState {
	data: ContactsFriends
	userId?: number
	callback: Callback
	index: number
	parentIndex: number
}
interface SearchState {
	userInfo: User
	value: string
	type: SearchType
	visible: boolean
	loading: boolean
	menu: MenuItem[]
	verification: string
	// 用户过滤搜索
	userFilter: ContactsFriends[]
	axis?: {
		x: number
		y: number
	}
}
export default defineComponent({
	name: 'AddressList',
	setup() {
		const router = useRouter()
		const userId = localStorage.getItem('userId') as string
		// 用户id集合
		const userIds = ref<number[]>([])
		// 好友备注集合
		const friendsRemarksMap = computed<Map<string, string>>(() => {
			return BasicDataModule.friendsRemarksMap
		})
		const rightType = ref(DoRightType.userInfo)
		const sendMessageMenuItem = {
			text: '发消息',
			handler: hanleSendMessage,
		}
		const searchStateMenuItem = [
			{
				text: '添加到通讯录',
				hide: false,
				handler: switchAddFriendsState,
			},
			{
				text: '验证消息',
				hide: true,
				slots: verifyMessageRender,
			},
		]
		const userInfoState = ref<UserInfoState>({
			userInfo: {},
			groupChatInfo: undefined,
			loading: false,
			menu: [clone(sendMessageMenuItem)],
		})
		// 通讯录列表
		const contacts = computed<PySegSort[]>(() => {
			const contact = clone(BasicDataModule.contacts)
			return pySegSort(contact)
		})
		watch(
			BasicDataModule.contacts,
			() => {
				userIds.value = BasicDataModule.contacts.map((item) => item.friendsId) as number[]
			},
			{
				immediate: true,
				deep: true,
			}
		)
		function openUserInfo(data: ContactsFriends | ChatUserGroup) {
			// 清除内置用户菜单选中事件
			clearBuiltInUserMenuIsActive()
			rightType.value = DoRightType.userInfo
			userInfoState.value.groupChatInfo = undefined
			userInfoState.value.userInfo = {}
			if (equals((data as ContactsFriends).classType, 1)) {
				const contactsFriends = data as ContactsFriends
				userInfoState.value.userInfo = {
					id: contactsFriends.friendsId,
					username: contactsFriends.friendsName,
					account: contactsFriends.friends?.account,
					sex: contactsFriends.friends?.sex,
					age: contactsFriends.friends?.age,
					headimgurl: contactsFriends.friends?.headimgurl,
					remarks: contactsFriends.remarks,
					source: contactsFriends.source,
					classType: contactsFriends.classType,
				}
			}

			if (equals(data.classType, 2)) {
				const chatUserGroup = data as ChatUserGroup
				userInfoState.value.groupChatInfo = clone(chatUserGroup)
			}
		}
		// 发消息并添加聊天历史记录
		async function hanleSendMessage() {
			const historicalUserSessionsId = searchState.value.visible
				? String(searchState.value.userInfo.id)
				: isTrue(userInfoState.value.userInfo?.id)
				? String(userInfoState.value.userInfo?.id)
				: userInfoState.value.groupChatInfo?.group_id
			searchState.value.loading = true
			userInfoState.value.loading = true
			const success = await onSendMessage(historicalUserSessionsId as string)
			searchState.value.loading = false
			userInfoState.value.loading = false
			if (success) {
				toChat(historicalUserSessionsId as string)
			}
		}
		function toChat(userId: string) {
			router.push({
				path: '/index',
				query: {
					userId,
				},
			})
		}

		const searchState = ref<SearchState>({
			value: '',
			type: SearchType.contactsSearch,
			userInfo: {},
			verification: '',
			loading: false,
			visible: false,
			menu: clone(searchStateMenuItem),
			userFilter: [],
			axis: {
				x: 385,
				y: 85,
			},
		})
		function verifyMessageRender() {
			return (
				<div>
					<a-textarea
						v-model={[searchState.value.verification, 'value']}
						placeholder="请输入验证消息"
						rows={3}
						autosize={{ minRows: 3, maxRows: 3 }}
					/>
					<a-button type="primary" style="margin-top:10px" onClick={addChatUserFriends}>
						确定
					</a-button>
					<a-button style="margin:10px 0 0 10px" onClick={switchAddFriendsState}>
						取消
					</a-button>
				</div>
			)
		}
		function switchAddFriendsState() {
			searchState.value.menu[1].hide = searchState.value.menu[0].hide
			searchState.value.menu[0].hide = !searchState.value.menu[1].hide
		}
		// /**
		//  * 搜索类型
		//  */
		// const isContactsSearch = computed(() => {
		// 	return equals(SearchType.contactsSearch, searchState.value.type)
		// })
		/**
		 * 搜索用户
		 */
		async function onSearchUser(userInfo?: User) {
			if (!searchState.value) return
			let requestData = {
				success: false,
				data: {} as User,
			}
			searchState.value.axis = {
				x: 385,
				y: 85,
			}
			if (isTrue(userInfo)) {
				searchState.value.axis = undefined
				requestData.success = true
				requestData.data = userInfo as User
			} else {
				requestData = await API.blog.chatUser.getUserInfo.request({ account: searchState.value.value })
			}
			if (requestData.success && requestData.data) {
				searchState.value.visible = true
				searchState.value.userInfo = clone(requestData.data) as User
				if (equals(Number(userId), requestData.data.id)) {
					searchState.value.menu = []
				} else if (userIds.value.includes(requestData.data.id as number)) {
					searchState.value.menu = [clone(sendMessageMenuItem)]
				} else {
					searchState.value.menu = clone(searchStateMenuItem)
				}
			}
		}
		async function addChatUserFriends() {
			if (!isTrue(searchState.value.userInfo)) {
				errorTips('搜索用户不存在')
				return
			}
			if (!isTrue(searchState.value.verification)) {
				errorTips('请输入验证信息')
				return
			}
			searchState.value.loading = true
			const { success } = await API.blog.chatUserFriends.addChatUserFriends.request({
				userId: Number(userId),
				friendsId: searchState.value.userInfo.id,
				verification: searchState.value.verification,
			})
			searchState.value.loading = false
			if (success) {
				successTips('添加成功，请等待验证通过')
				cancelFollow()
			}
		}
		/**
		 * 关闭弹窗
		 */
		function cancelFollow() {
			searchState.value.userInfo = {}
			searchState.value.verification = ''
			searchState.value.visible = false
			searchState.value.menu[0] && (searchState.value.menu[0].hide = false)
			searchState.value.menu[1] && (searchState.value.menu[1].hide = true)
		}
		/**
		 * 内置用户菜单
		 */
		const builtInUserMenu = reactive<BuiltInUserMenu[]>([
			{
				letter: '新的朋友',
				menu: [
					{
						title: '新的朋友',
						icon: <IconAddUser />,
						backgroundColor: '#FA9D3B',
						isActive: false,
					},
				],
			},
		])
		function openRightView(data: BuiltInUserMenuItem) {
			rightType.value = DoRightType.newFriends
			userInfoState.value.userInfo = {}
			userInfoState.value.groupChatInfo = undefined
			data.isActive = true
		}
		/** 清除内置用户菜单选中事件 */
		function clearBuiltInUserMenuIsActive() {
			builtInUserMenu.forEach((item) => {
				item.menu.forEach((res) => {
					res.isActive = false
				})
			})
		}
		function onSearchBtnEvent() {
			searchState.value.value = ''
		}

		/**
		 *
		 * @param data 用户
		 * @param userInfoState 打开
		 * @returns
		 */
		function userRender({ data, userId, callback, index, parentIndex }: UserRenderState) {
			return (
				<li
					class={equals(userId, data.friendsId ?? data.groupChat.group_id) ? 'active' : ''}
					onClick={() => callback.openUserInfo(data)}
					v-contextmenu={contextmenu}
					data-index={index}
					parent-index={parentIndex}
				>
					<div class="headimgurl">
						<UserImg iconSize={44} imgSize={44} headimgurl={data.friends?.headimgurl} />
					</div>
					<div class="name one-hidden">
						{friendsRemarksMap.value.get(String(data.friendsId)) ?? data.friendsName ?? data.groupChat.groupChatName}
					</div>
				</li>
			)
		}
		// injectSendMessage(userInfoState.value.userInfo as User)
		const contextmenu = (): ContextmenuItem[] => {
			return [
				{
					text: '发消息',
					handler: async (e: { getAttribute: (arg0: string) => any }) => {
						const parentIndex = e.getAttribute('parent-index') as any
						const index = e.getAttribute('data-index')
						const dataSource = contacts.value[parentIndex].data[index]
						if (equals(dataSource.classType, 1)) {
							userInfoState.value.userInfo = {
								id: dataSource.friendsId,
								username: dataSource.friendsName,
								account: dataSource.friends?.account,
								sex: dataSource.friends?.sex,
								age: dataSource.friends?.age,
								headimgurl: dataSource.friends?.headimgurl,
								remarks: dataSource.remarks,
								source: dataSource.source,
							}
						}
						if (equals(dataSource.classType, 2)) {
							userInfoState.value.groupChatInfo = clone(dataSource) as any
						}
						hanleSendMessage()
					},
				},
				{
					text: '删除朋友',
					handler: delChatUserFriends,
				},
			]
		}
		async function delChatUserFriends(e: { getAttribute: (arg0: string) => any }) {
			const parentIndex = e.getAttribute('parent-index')
			const index = e.getAttribute('data-index')
			const dataSource = contacts.value[parentIndex].data[index]
			const { success, msg } = await API.blog.chatUserFriends.delChatUserFriends.request({
				userId,
				friendsId: dataSource.friendsId,
			})
			success ? successTips(msg) : errorTips(msg)
			if (success) {
				BasicDataModule.getContacts()
			}
		}
		return () => (
			<div class="contacts">
				<div class="contacts-left">
					{[SearchType.contactsSearch, SearchType.userFilter].includes(searchState.value.type) && (
						<FormSearch
							v-model={[searchState.value.value, 'value']}
							prefixIcon={<SearchOutlined style={{ fontSize: $styles.searchIconSize }} />}
							btnIcon={<UserAddOutlined />}
							onBtnEvent={() => {
								searchState.value.type = SearchType.userSearch
								onSearchBtnEvent()
							}}
							onChange={(value: string) => {
								searchState.value.type = SearchType.userFilter
								if (isTrue(value) && equals(searchState.value.type, SearchType.userFilter)) {
									searchState.value.userFilter = searchFilter<ContactsFriends[]>(
										BasicDataModule.contacts,
										value
									) as ContactsFriends[]
								} else {
									searchState.value.type = SearchType.contactsSearch
									searchState.value.userFilter = []
								}
							}}
						/>
					)}
					{equals(SearchType.userSearch, searchState.value.type) && (
						<FormSearch
							v-model={[searchState.value.value, 'value']}
							prefixIcon={<UsergroupAddOutlined style={{ fontSize: $styles.searchIconSize }} />}
							btnIcon={'取消'}
							onBtnEvent={() => {
								searchState.value.type = SearchType.contactsSearch
								onSearchBtnEvent()
								searchState.value.userFilter = []
							}}
						/>
					)}
					{/* 联系人 */}
					{equals(SearchType.contactsSearch, searchState.value.type) && (
						<Scroll height="calc(100% - 50px)">
							<ol class="user-list-box">
								{builtInUserMenu.map((item) => (
									<li>
										<div class="letter">{item.letter}</div>
										<ul class="user-list">
											{item.menu.map((data) => (
												<li onClick={() => openRightView(data)} class={data.isActive ? 'active' : ''}>
													<div class="user-icon" style={{ background: data.backgroundColor }}>
														<a-badge
															count={BasicDataModule.unreadFriendsTotalCount}
															overflow-count={999}
															offset={[0, 0]}
														/>
														{h(data.icon)}
													</div>
													<div class="name one-hidden">{data.title}</div>
												</li>
											))}
										</ul>
									</li>
								))}
							</ol>
							<ol class="user-list-box">
								{contacts.value.map((item, parentIndex) => {
									return (
										<li>
											<div class="letter">{item.letter}</div>
											<ul class="user-list">
												{item.data?.map((data, index) => {
													return userRender({
														data,
														userId:
															(userInfoState.value.userInfo?.id as number) ??
															userInfoState.value.groupChatInfo?.group_id,
														callback: { openUserInfo },
														index,
														parentIndex,
													})
												})}
											</ul>
										</li>
									)
								})}
							</ol>
						</Scroll>
					)}
					{/* 用户搜索 */}
					{equals(SearchType.userSearch, searchState.value.type) && searchState.value.value && (
						<div class="search-user" onClick={() => onSearchUser()}>
							<div class="search-prefix">
								<a-button
									type="primary"
									icon={<SearchOutlined style={{ fontSize: $styles.searchIconSize }} />}
								></a-button>
							</div>
							<div class="search-middle ">
								搜索：<span class="one-hidden">{searchState.value.value}</span>
							</div>
							<div class="search-suffix">
								<RightOutlined style="color:#B0B0B0" />
							</div>
						</div>
					)}
					{/* 搜索 */}
					{equals(searchState.value.type, SearchType.userFilter) && isTrue(searchState.value.userFilter) && (
						<ul class="user-list">
							{searchState.value.userFilter?.map((data, index) => {
								return userRender({
									data,
									userId: undefined,
									callback: {
										openUserInfo: () => {
											toChat(equals(data.classType, 1) ? String(data.friendsId) : data.groupChat.group_id)
										},
									},
									index,
									parentIndex: 0,
								})
							})}
						</ul>
					)}
				</div>
				{/* 用户详情 */}
				{equals(rightType.value, DoRightType.userInfo) && isTrue(userInfoState.value.userInfo) && (
					<div class="userInfo-box">
						<UserInfo
							dataSource={userInfoState.value.userInfo as User}
							v-model={[userInfoState.value.loading, 'loading']}
							menu={userInfoState.value.menu}
						/>
					</div>
				)}
				{isTrue(userInfoState.value.groupChatInfo) && (
					<GroupChatInfo
						groupChat={userInfoState.value.groupChatInfo as ChatUserGroup}
						onUserInfo={(userInfo) => {
							onSearchUser(userInfo)
						}}
					/>
				)}
				{equals(rightType.value, DoRightType.newFriends) && <NewFriends />}
				<FormFollow
					v-model={[searchState.value.visible, 'visible']}
					loading={searchState.value.loading}
					axis={searchState.value.axis}
					onCancel={cancelFollow}
				>
					<UserInfo
						dataSource={searchState.value.userInfo}
						showRemarks={false}
						menu={searchState.value.menu}
						showMore={false}
						v-model={[searchState.value.loading, 'loading']}
					/>
				</FormFollow>
			</div>
		)
	},
})
